// author: Shelman
// description: 封装的使用posix接口实现的TCP服务端
#pragma once


#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <map>
#include <functional>

#include "GlobalDef.h"


// TCP服务端
class TcpServer
{
public:
    /*****************************************************
     * 功能：构造函数
     * ***************************************************/
    TcpServer();

    /*****************************************************
     * 功能：析构函数
     * ***************************************************/
    virtual ~TcpServer();

    /*****************************************************
     * 功能：不主动调用read接口获取数据时，设置接收数据的回调，
     * 输入参数：
     *      pfnCallback：数据回调函数
     * ***************************************************/
    void setDataRecvCallback(const DataReceivedCallback &pfnCallback);

    /*****************************************************
     * 功能：开启服务
     * 输入参数：
     *      stConnInfo：服务端的连接信息
     * 返回值：
     *      bool：开启结果，true -- 成功，false -- 失败
     * ***************************************************/
    bool start(const NetworkConnInfo &stConnInfo);

    /*****************************************************
     * 功能：停止服务
     * ***************************************************/
    void stop();

    /*****************************************************
     * 功能：向客户端发送数据
     * 输入参数：
     *      iClientSockFd：客户端socket通信句柄
     *      strData：待发送的数据
     * 返回值：
     *      bool：发送结果，true -- 发送成功，false -- 发送失败
     * ***************************************************/
    bool sendData(int iClientSockFd, const std::string &strData);

    /*****************************************************
     * 功能：向客户端读取数据
     * 输出参数：
     *      iClientSockFd：客户端socket通信句柄
     *      strData：待读取的数据的缓存区
     * 返回值：
     *      bool：读取结果，true -- 读取成功，false -- 读取失败
     * ***************************************************/
    bool recvData(int iClientSockFd, std::string &strData);

    /*****************************************************
     * 功能：获取客户端地址信息
     * 输出参数：
     *      iClientSockFd：客户端socket通信句柄
     * 返回值：
     *      std::string：客户端地址信息，格式ip:port
     * ***************************************************/
    std::string getClientAddrInfo(int iClientSockFd);

private:
    /*****************************************************
     * 功能：处理客户端的连接
     * ***************************************************/
    void acceptConnections();

    /*****************************************************
     * 功能：处理客户端业务
     * 输出参数：
     *      iClientSockFd：客户端socket通信句柄
     * ***************************************************/
    void handleClient(int iClientSockFd);

    /*****************************************************
     * 功能：关闭socket
     * 输入参数：
     *      iSockId：需要关闭socket的id信息
     * ***************************************************/
    void closeSocket(int iSockId);

private:
    volatile bool m_bRunning = false; // 是否运行服务的标志
    int m_iSrvSockFd = -1; // 服务器socket句柄

    NetworkConnInfo m_stConnInfo; // 服务端连接信息

    //std::mutex m_mt4SendData; // 发送数据互斥锁
    //std::mutex m_mt4RecvData; // 接收数据互斥锁

    std::thread m_th4AcceptClient; // 接受连接的线程

    std::mutex m_mt4ClientFds; // 客户端通信句柄资源锁
    std::map<int, std::string> m_mp4ClientFds; // 客户端通信句柄集合，key：fd，value：ip:port
    
    std::mutex m_mt4PfnCallback;          // 回调函数互斥锁
    DataReceivedCallback m_pfn4RecvDataCb; // 数据接收回调函数
};

